package com.wg.core.io;

import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.util.Collection;

/**
 * 二进制数据写入接口
 *
 * <p>提供大端序(big-endian)格式的二进制数据写入能力，
 * 支持基本类型、字符串、数组、集合和自定义可序列化对象的写入操作。</p>
 *
 * @author 少爷123
 */
public interface IBinaryWriter {

    /**
     * 获取当前写入的字节数组
     *
     * @return 包含所有已写入数据的字节数组
     */
    byte[] toByteArray();

    // ===================== 布尔类型 =====================

    /**
     * 写入单个布尔值
     *
     * @param value 要写入的布尔值
     */
    void writeBoolean(boolean value);

    /**
     * 写入布尔值数组
     *
     * @param values 要写入的布尔值数组
     */
    void writeBooleanArray(boolean[] values);

    /**
     * 写入布尔值集合
     *
     * @param collection 要写入的布尔值集合
     */
    void writeBooleanCollection(Collection<Boolean> collection);

    // ===================== 字节类型 =====================

    /**
     * 写入单个字节
     *
     * @param value 要写入的字节值
     */
    void writeByte(byte value);

    /**
     * 写入原始字节数组（不包含长度信息）
     *
     * @param value 要写入的字节数组
     */
    void writeRawBytes(byte[] value);

    /**
     * 写入字节数组（包含长度信息）
     *
     * @param value 要写入的字节数组
     */
    void writeBytes(byte[] value);

    // ===================== 字符类型 =====================

    /**
     * 写入单个字符
     *
     * @param value 要写入的字符值
     */
    void writeChar(char value);

    /**
     * 写入字符数组
     *
     * @param values 要写入的字符数组
     */
    void writeCharArray(char[] values);

    // ===================== 双精度浮点 =====================

    /**
     * 写入双精度浮点数
     *
     * @param value 要写入的双精度浮点值
     */
    void writeDouble(double value);

    /**
     * 写入双精度浮点数组
     *
     * @param values 要写入的双精度浮点数组
     */
    void writeDoubleArray(double[] values);

    /**
     * 写入双精度浮点集合
     *
     * @param collection 要写入的双精度浮点集合
     */
    void writeDoubleCollection(Collection<Double> collection);

    // ===================== 短整型 =====================

    /**
     * 写入短整型数值
     *
     * @param value 要写入的短整型值
     */
    void writeShort(short value);

    /**
     * 写入短整型数组
     *
     * @param values 要写入的短整型数组
     */
    void writeShortArray(short[] values);

    /**
     * 写入短整型集合
     *
     * @param collection 要写入的短整型集合
     */
    void writeShortCollection(Collection<Short> collection);

    // ===================== 整型 =====================

    /**
     * 写入整型数值
     *
     * @param value 要写入的整型值
     */
    void writeInt(int value);

    /**
     * 写入大整数(BigInteger)值
     *
     * @param value 要写入的大整数值
     */
    void writeBigInteger(BigInteger value);

    /**
     * 写入整型数组
     *
     * @param values 要写入的整型数组
     */
    void writeIntArray(int[] values);

    /**
     * 写入整型集合
     *
     * @param collection 要写入的整型集合
     */
    void writeIntCollection(Collection<Integer> collection);

    // ===================== 长整型 =====================

    /**
     * 写入长整型数值
     *
     * @param value 要写入的长整型值
     */
    void writeLong(long value);

    /**
     * 写入长整型数组
     *
     * @param values 要写入的长整型数组
     */
    void writeLongArray(long[] values);

    /**
     * 写入长整型集合
     *
     * @param collection 要写入的长整型集合
     */
    void writeLongCollection(Collection<Long> collection);

    // ===================== 单精度浮点 =====================

    /**
     * 写入单精度浮点数
     *
     * @param value 要写入的单精度浮点值
     */
    void writeFloat(float value);

    /**
     * 写入单精度浮点数组
     *
     * @param values 要写入的单精度浮点数组
     */
    void writeFloatArray(float[] values);

    /**
     * 写入单精度浮点集合
     *
     * @param collection 要写入的单精度浮点集合
     */
    void writeFloatCollection(Collection<Float> collection);

    // ===================== 字符串 =====================

    /**
     * 写入字符串（支持长字符串特殊处理）
     *
     * @param value 要写入的字符串
     */
    void writeString(String value);

    /**
     * 写入字符串数组
     *
     * @param values 要写入的字符串数组
     */
    void writeStringArray(String[] values);

    /**
     * 写入字符串集合
     *
     * @param collection 要写入的字符串集合
     */
    void writeStringCollection(Collection<String> collection);

    // ===================== 可序列化对象 =====================

    /**
     * 写入可序列化对象
     *
     * @param <T>    实现ISerializerWrite接口的类型
     * @param object 要写入的可序列化对象
     */
    <T extends IBinaryWritable> void writeObject(T object);

    /**
     * 写入可序列化对象数组
     *
     * @param <T>   实现ISerializerWrite接口的类型
     * @param array 要写入的可序列化对象数组
     */
    <T extends IBinaryWritable> void writeObjectArray(T[] array);

    /**
     * 写入可序列化对象集合
     *
     * @param <T>        实现ISerializerWrite接口的类型
     * @param collection 要写入的可序列化对象集合
     */
    <T extends IBinaryWritable> void writeObjectCollection(Collection<T> collection);

    // ===================== 流操作 =====================

    /**
     * 获取底层字节输出流
     *
     * @return 底层字节输出流
     */
    ByteArrayOutputStream baseStream();
}